package com.ruoyi.api.event;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 事件中心实现类
 */
@Component
public class EventCenter implements EventPublisher {
    
    private static final Logger logger = LoggerFactory.getLogger(EventCenter.class);
    
    /**
     * 事件监听器映射
     */
    private final Map<EventType, List<EventListener<?>>> listenerMap = new HashMap<>();
    
    /**
     * 注册事件监听器
     * 
     * @param listener 监听器
     */
    public <T> void registerListener(EventListener<T> listener) {
        EventType eventType = listener.getSupportedEventType();
        List<EventListener<?>> listeners = listenerMap.computeIfAbsent(eventType, k -> new ArrayList<>());
        listeners.add(listener);
        logger.info("Registered event listener: {} for event type: {}", listener.getClass().getName(), eventType);
    }
    
    /**
     * 发布事件
     */
    @Override
    public void publishEvent(OrderExecutionEvent event) {
        publishEventInternal(event);
    }
    
    /**
     * 发布交易记录事件
     */
    public void publishEvent(TransactionEvent event) {
        publishEventInternal(event);
    }
    
    /**
     * 内部事件发布方法
     */
    private <T> void publishEventInternal(T event) {
        EventType eventType = getEventType(event);
        List<EventListener<?>> listeners = listenerMap.get(eventType);
        
        if (listeners != null && !listeners.isEmpty()) {
            for (EventListener<?> listener : listeners) {
                try {
                    if (listener.getSupportedEventClass().isInstance(event)) {
                        invokeListener(listener, event);
                    }
                } catch (Exception e) {
                    logger.error("Error processing event {} in listener {}", eventType, listener.getClass().getName(), e);
                }
            }
        } else {
            logger.debug("No listeners registered for event type: {}", eventType);
        }
    }
    
    /**
     * 安全地调用监听器
     */
    @SuppressWarnings("unchecked")
    private <T> void invokeListener(EventListener<?> listener, T event) {
        ((EventListener<T>) listener).onEvent(event);
    }
    
    /**
     * 获取事件类型
     */
    private EventType getEventType(Object event) {
        if (event instanceof OrderExecutionEvent) {
            return ((OrderExecutionEvent) event).getEventType();
        } else if (event instanceof TransactionEvent) {
            return ((TransactionEvent) event).getEventType();
        } else {
            throw new IllegalArgumentException("Unsupported event type: " + event.getClass().getName());
        }
    }
} 